//
//  RootViewController.m
//  FuelLog
//
//  Created by Olaf on 13.06.10.
//  Copyright __MyCompanyName__ 2010. All rights reserved.
//

#import "RootViewController.h"
#import "DebugOutput.h"

#define _carSection		0
#define _statsSection	1


@interface RootViewController ()
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath;
@end


@implementation RootViewController
@synthesize currentCar;
@synthesize carsButton, prefsButton ,statsButton ,addButton, toolBarSpacer;

@synthesize fetchedResultsController, managedObjectContext;


#pragma mark -
- (id)initWithStyle:(UITableViewStyle)style {
	debug(@"in init withStyle");
    if (self = [super initWithStyle:style]) {
		//  		debug(@"in init withStyle if-statement");
		carsButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Auto2.png"] //initWithTitle: (NSLocalizedString(@"Cars", @""))
													  style:UIBarButtonItemStyleBordered
													 target:self
													 action:@selector(addCar:)];
		prefsButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"19-gear.png"] //initWithTitle: (NSLocalizedString(@"Prefs", @""))
													   style:UIBarButtonItemStyleBordered
													  target:self
													  action:@selector(setPrefs:)];
		statsButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"graph.png"]// initWithTitle: (NSLocalizedString(@"Stats", @""))
													   style:UIBarButtonItemStyleBordered
													  target:self
													  action:@selector(viewStats:)];
		addButton = [[UIBarButtonItem alloc ] initWithImage:[UIImage imageNamed:@"47-fuel.png"] //initWithTitle: (NSLocalizedString(@"Add", @""))
													  style:UIBarButtonItemStyleBordered
													 target:self
													 action:@selector(addGas:)];
		carsButton.enabled = YES;
		prefsButton.enabled = YES;
		statsButton.enabled = YES;
		addButton.enabled = YES;
		
		toolBarSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
																	  target:self
																	  action:nil];
		
		[self setToolbarItems:[NSArray arrayWithObjects:carsButton, 
							   toolBarSpacer, prefsButton,
							   toolBarSpacer, statsButton,
							   toolBarSpacer, addButton,
							   nil] animated:NO];
		
		[self.toolbarItems makeObjectsPerformSelector:@selector(release)];
	}
	debug(@"in initWithStyle outside if");
	return self;
}

#pragma mark View lifecycle

- (void)viewDidLoad {
    [super viewDidLoad];
 
    NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error]) {
        /*
         Replace this implementation with code to handle the error appropriately.
         
         abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
         */
        debug(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
	debug(@"%d objects fetched", [[fetchedResultsController fetchedObjects] count]);
	if ([[fetchedResultsController fetchedObjects] count] == 0) [self populateEmptyPersistanceStore];

}


 - (void)viewWillAppear:(BOOL)animated {
 [super viewWillAppear:animated];
 	[self.navigationController setToolbarHidden:NO animated:YES];
 }

/*
 - (void)viewDidAppear:(BOOL)animated {
 [super viewDidAppear:animated];
 }
 */
/*
 - (void)viewWillDisappear:(BOOL)animated {
 [super viewWillDisappear:animated];
 }
 */
/*
 - (void)viewDidDisappear:(BOOL)animated {
 [super viewDidDisappear:animated];
 }
 */

/*
 // Override to allow orientations other than the default portrait orientation.
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
 // Return YES for supported orientations.
 return (interfaceOrientation == UIInterfaceOrientationPortrait);
 }
 */


- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    debug(@"in configureCell");
	
	  NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
		debug(@"managedObject %@",managedObject);
	currentCar = [managedObject valueForKey:@"Name"];
    cell.textLabel.text =[currentCar description];
	
	cell.detailTextLabel.text = @"Detail"; //[[managedObject valueForKey:@"ID"] description];
}

#pragma mark -
#pragma mark Fetched results controller

- (NSFetchedResultsController *)fetchedResultsController {
    
    if (fetchedResultsController != nil) {
        return fetchedResultsController;
    }
	
    /*
     Set up the fetched results controller.
	 */
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
	NSPredicate * predicate = [NSPredicate predicateWithFormat:@"Selected = 1"];// , self.predicateString];
	[fetchRequest setPredicate:predicate];
	
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];
    
    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];
    
    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"DateAdded" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    
    [fetchRequest setSortDescriptors:sortDescriptors];
    
    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;
    
    [aFetchedResultsController release];
    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];
    
    return fetchedResultsController;
}    


#pragma mark -
#pragma mark Fetched results controller delegate


- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView beginUpdates];
}


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
    
    switch(type) {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
            
        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath {
    
    UITableView *tableView = self.tableView;
    
    switch(type) {
            
        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
            
        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
            
        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;
            
        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView endUpdates];
}


/*
 // Implementing the above methods to update the table view in response to individual changes may have performance implications if a large number of changes are made simultaneously. If this proves to be an issue, you can instead just implement controllerDidChangeContent: which notifies the delegate that all section and object changes have been processed. 
 
 - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
 // In the simplest, most efficient, case, reload the table view.
 [self.tableView reloadData];
 }
 */


#pragma mark -
-(void) populateEmptyPersistanceStore {
	// Create a new instance of the entity managed by the fetched results controller.
    NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
    NSEntityDescription *entity = [[fetchedResultsController fetchRequest] entity];
    NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
    
    // If appropriate, configure the new managed object.
	[newManagedObject setValue:[NSDate date] forKey:@"DateAdded"];
	[newManagedObject setValue:[NSNumber numberWithInt:0] forKey:@"ID"];
	[newManagedObject setValue:@"My Car" forKey:@"Name"];
	[newManagedObject setValue:@"" forKey:@"NumberPlate"];
	[newManagedObject setValue:[NSNumber numberWithBool:YES] forKey:@"Selected"];
	
	
    // Save the context.
    NSError *error = nil;
    if (![context save:&error]) {
        /*
         Replace this implementation with code to handle the error appropriately.
         
         abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
         */
        debug(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
	
}
#pragma mark -
#pragma mark Add a new object

- (void)insertNewObject {
    
    // Create a new instance of the entity managed by the fetched results controller.
    NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
    NSEntityDescription *entity = [[fetchedResultsController fetchRequest] entity];
    NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
    
    // If appropriate, configure the new managed object.
    [newManagedObject setValue:[NSDate date] forKey:@"DateAdded"];
    [newManagedObject setValue:[NSNumber numberWithBool:NO] forKey:@"Selected"];
	/*    [newManagedObject setValue:[NSDate date] forKey:@"DateAdded"];
	 [newManagedObject setValue:[NSDate date] forKey:@"DateAdded"];
	 [newManagedObject setValue:[NSDate date] forKey:@"DateAdded"];
	 */  
    // Save the context.
    NSError *error = nil;
    if (![context save:&error]) {
        /*
         Replace this implementation with code to handle the error appropriately.
         
         abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
         */
        debug(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
}

#pragma mark -
#pragma mark Buttons

- (IBAction)addCar:(id)sender {
	if (carsController == nil) { 
		carsController = [[CarsViewController alloc] initWithStyle:UITableViewStyleGrouped];
	} 
	UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] 
									  initWithTitle:  (NSLocalizedString(@"Cancel", @"")) 
									  style: UIBarButtonItemStyleBordered 
									  target: nil 
									  action: nil];
	[self.navigationItem setBackBarButtonItem: newBackButton];
	carsController.managedObjectContext = self.managedObjectContext;
	[self.navigationController pushViewController:carsController animated:YES];
	[newBackButton release];
}
/*
- (IBAction)addGas:(id)sender {
	if (gasController == nil) { 
		gasController = [[GasViewController alloc] initWithStyle:UITableViewStyleGrouped];
	}
/*	FuelLogAppDelegate *appDelegate = (FuelLogAppDelegate *)[[UIApplication sharedApplication] delegate];
	Gas *gas = [[Gas alloc] init:appDelegate.currentCar]; * /
	Gas *gas = currentCar;
	[gasController setGas:gas];
	[gasController setBoxes];
	[gasController setTitle:(NSLocalizedString(@"Add Gas", @"Update Gas"))];
	UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] 
									  initWithTitle:  (NSLocalizedString(@"Cancel", @"")) 
									  style: UIBarButtonItemStyleBordered 
									  target: nil 
									  action: nil];
	[self.navigationItem setBackBarButtonItem: newBackButton];
	
	[self.navigationController pushViewController:gasController animated:YES];
	[newBackButton release];
	
}
*/
- (IBAction)viewStats:(id)sender {
	if (statsController == nil) { 
		statsController = [[StatsViewController alloc] initWithStyle:UITableViewStyleGrouped];
		
	} 
	[self.navigationController pushViewController:statsController animated:YES];
	
}

- (IBAction)setPrefs:(id)sender {
	if (prefsController == nil) { 
		prefsController = [[PrefsViewController alloc] initWithStyle:UITableViewStyleGrouped];
	} 
	UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] 
									  initWithTitle:  (NSLocalizedString(@"Cancel", @"")) 
									  style: UIBarButtonItemStyleBordered 
									  target: nil 
									  action: nil];
	[[self navigationItem] setBackBarButtonItem: newBackButton];
	[self.navigationController pushViewController:prefsController animated:YES];
	[newBackButton release];
	
}
#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
	//    return 1; //
	return [[fetchedResultsController sections] count]+1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
	//    id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
	//    return [sectionInfo numberOfObjects];
	NSInteger returnValue = 0;
	switch (section) {
		case _carSection:
			returnValue = 1;
			break;
		case _statsSection:
			returnValue = 1;
		default:
			break;
	}
	return returnValue;
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle  reuseIdentifier:CellIdentifier] autorelease];
    }
    
    // Configure the cell.
	debug(@"indexpath section %d, row %d",indexPath.row, indexPath.section);
	if (indexPath.section == 0) 
		[self configureCell:cell atIndexPath:indexPath];
    else {
		cell.textLabel.text = @"Empty cell";
		cell.detailTextLabel.text = @"Detail"; 
	}
	
    return cell;
}



/*
 // Override to support conditional editing of the table view.
 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
 // Return NO if you do not want the specified item to be editable.
 return YES;
 }
 */


// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the managed object for the given index path
        NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
        [context deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]];
        
        // Save the context.
        NSError *error = nil;
        if (![context save:&error]) {
            /*
             Replace this implementation with code to handle the error appropriately.
             
             abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
             */
			debug(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }   
}


- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
    // The table view should not be re-orderable.
    return NO;
}


#pragma mark -
#pragma mark Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // Navigation logic may go here -- for example, create and push another view controller.
    /*
     <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
     NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
     // ...
     // Pass the selected object to the new view controller.
     [self.navigationController pushViewController:detailViewController animated:YES];
     [detailViewController release];
     */
	[tableView deselectRowAtIndexPath:indexPath animated:YES];
}



#pragma mark -
#pragma mark Memory management

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Relinquish ownership any cached data, images, etc that aren't in use.
}


- (void)viewDidUnload {
    // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
    // For example: self.myOutlet = nil;
}


- (void)dealloc {
	[carsController release]; 
	[gasController release]; 
	[statsController release]; 
	[prefsController release];
	[carsButton release];
	[prefsButton release];
	[statsButton release];
	[addButton release];
	[toolBarSpacer release];
	
    [fetchedResultsController release];
    [managedObjectContext release];
    [super dealloc];
}


@end

